package com.oros.db;

import java.io.Serializable;
import java.util.HashSet;

import com.vaadin.data.Container;
import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Container.Filter;

public class AEJoinWithPrimaryIdFilter implements Serializable,
		AEExtendedFilter {
        
	private static final long serialVersionUID = -8842645998396795526L;
    private AETableContainer parentContainer=null;
    public AETableContainer joinedContainer;
    public Filter[] whereFilters;
    public String columnName;
    private HashSet<?> origin;
    int hashcode;
    private Container.ItemSetChangeListener listener=null;
    public AEJoinWithPrimaryIdFilter(AETableContainer joinedContainer,String columnName,
    		Filter[] whereFilters)
    {
    	this.joinedContainer = joinedContainer;
    	this.whereFilters = whereFilters;
    	this.columnName = columnName;
    	origin = joinedContainer.getDistinctColumnValues(null, whereFilters);
    	hashcode = joinedContainer.hashCode() ^ columnName.hashCode();
        if (whereFilters!=null)
        	for(int i=0;i<whereFilters.length;i++)
        		hashcode ^= whereFilters[i].hashCode();
        listener = new AEListenerClosable()
        {
			private static final long serialVersionUID = 1L;

			@Override
			public void containerItemSetChange(ItemSetChangeEvent event) {
				updateFilter();
			}

			@Override
			public boolean isClosed() {
				return isFilterClosed();
			}
        	
        };
        joinedContainer.addListener(listener);
    }
    final public boolean isFilterClosed()
    {
    	return parentContainer==null;
    }
    final public void updateFilter()
    {
        if (parentContainer!=null)
        {
        	if (!parentContainer.opened)
        	{
        		parentContainer = null;
        		listener = null;
        		joinedContainer = null;
        		return;
        	}
        	HashSet<?> neworigin = joinedContainer.getDistinctColumnValues(null, whereFilters);
        	if (!origin.equals(neworigin))
        	{
        		origin = neworigin;
                parentContainer.refilter_resorter();      
        	}
        }
    	
    }
	@Override
	public boolean passesFilter(Object itemId, Item item)
			throws UnsupportedOperationException {
		final Property p = item.getItemProperty(columnName);
		        if (null == p) {
		            return false;
		        }
		Object value = p.getValue();
		if (value==null) return false;
		return origin.contains(value);
	}

	@Override
	public boolean appliesToProperty(Object propertyId) {
		return columnName.equals(propertyId);
	}

	@Override
	public void onCloseEvent() {
		parentContainer = null;
        if (listener!=null && joinedContainer!=null)
        {
        	joinedContainer.removeListener(listener);
        }
    	listener=null;
    	joinedContainer=null;
	}

	@Override
	public void setParentContainer(AETableContainer container) {
		parentContainer = container;
	}
	@Override
    public boolean equals(Object obj) {
	        // Only objects of the same class can be equal
	        if (!getClass().equals(obj.getClass())) {
	            return false;
	        }
	        AEJoinWithPrimaryIdFilter filt=(AEJoinWithPrimaryIdFilter)obj;
	        if (!columnName.equals(filt.columnName)) return false;
	        if (joinedContainer!=filt.joinedContainer) return false;
	        if (whereFilters==null && filt.whereFilters==null) return true;
	        if (whereFilters==null || filt.whereFilters==null || 
	        		whereFilters.length!=filt.whereFilters.length)
	        	return false;
	        int n=whereFilters.length;
	        for(int i=0;i<n;i++)
	        	if (!whereFilters[i].equals(filt.whereFilters[i])) return false;
	        return true;
	}
	 @Override
     public int hashCode() { return hashcode; }
}
